/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/03/17
* File: Parameter.cpp
* Blog: http://www.cnblogs.com/zengqh/
**/

#include "Parameter.h"
#include <image/image.h>
#include "ParameterManager.h"
#include <math/string_util.h>
#include "RenderContext.h"

namespace HY
{
ParameterManager* Parameter::getParamMgr() const
{
	return mgr_;
}

uint32 Parameter::getType() const
{
	return type_;
}

const std::string& Parameter::getName() const
{
	return name_;
}

void Parameter::setName(const std::string& name)
{
	name_ = name;
}

std::string Parameter::getParamString() const
{
	return param_str_;
}

bool Parameter::setParamString(const std::string& value)
{
	param_str_ = value;

	switch (type_)
	{
	case Parameter::Texture_2d:
		setValueTexture2D(value);
		break;
	case Parameter::String:
		*static_cast<std::string*>(value_) = value;
		break;
	case Parameter::Integer:
		*static_cast<int32*>(value_) = to_int(value);
		break;
	case Parameter::Integer2:
		*static_cast<IntVector2*>(value_) = to_intvec2(value);
		break;
	case Parameter::Integer3:
	case Parameter::Integer4:
		HY_ASSERT(0);
		break;
	case Parameter::Float:
		*static_cast<float*>(value_) = to_float(value);
		break;
	case Parameter::Float2:
		*static_cast<Vector2*>(value_) = to_vec2(value);
		break;
	case Parameter::Float3:
		*static_cast<Vector3*>(value_) = to_vec3(value);
		break;
	case Parameter::Float4:
		*static_cast<Vector4*>(value_) = to_vec4(value);
		break;
	default:
		HY_ASSERT(0);
		return false;
	}
	
	return true;
}

bool Parameter::getValue1i(int& x) const
{
	if (type_ != Parameter::Integer)
	{
		return false;
	}

	x = *static_cast<const int*>(value_);
	return true;
}

bool Parameter::setValue1i(int x)
{
	if (type_ != Parameter::Integer)
	{
		return false;
	}

	*static_cast<int*>(value_) = x;

	return true;
}

bool Parameter::getValue2i(int& x, int& y) const
{
	if (type_ != Parameter::Integer2)
	{
		return false;
	}

	x = static_cast<const int*>(value_)[0];
	y = static_cast<const int*>(value_)[1];

	return true;
}

bool Parameter::setValue2i(int x, int y)
{
	if (type_ != Parameter::Integer2)
	{
		return false;
	}

	static_cast<int*>(value_)[0] = x;
	static_cast<int*>(value_)[1] = y;

	return true;
}

bool Parameter::setValue2iv(const int value[])
{
	if (type_ != Parameter::Integer2)
	{
		return false;
	}

	static_cast<int*>(value_)[0] = value[0];
	static_cast<int*>(value_)[1] = value[0];

	return true;
}

bool Parameter::getValue1f(float& x) const
{
	if (type_ != Parameter::Float)
	{
		return false;
	}

	x = *static_cast<const float*>(value_);

	return true;
}

bool Parameter::setValue1f(float x)
{
	if (type_ != Parameter::Float)
	{
		return false;
	}

	*static_cast<float*>(value_) = x;

	return true;
}

bool Parameter::getValue2f(float& x, float& y) const
{
	if (type_ != Parameter::Float2)
	{
		return false;
	}

	x = static_cast<const float*>(value_)[0];
	y = static_cast<const float*>(value_)[1];

	return true;
}

bool Parameter::setValue2f(float x, float y)
{
	if (type_ != Parameter::Float2)
	{
		return 0;
	}

	static_cast<float*>(value_)[0] = x;
	static_cast<float*>(value_)[1] = y;

	return true;
}	

bool Parameter::setValue2if(const float value[])
{
	if (type_ != Parameter::Float2)
	{
		return false;
	}

	static_cast<float*>(value_)[0] = value[0];
	static_cast<float*>(value_)[1] = value[1];

	return true;
}

bool Parameter::getValue3f(float& x, float& y, float& z) const
{
	if (type_ != Parameter::Float3)
	{
		return false;
	}

	x = static_cast<const float*>(value_)[0];
	y = static_cast<const float*>(value_)[1];
	z = static_cast<const float*>(value_)[2];

	return true;
}

bool Parameter::setValue3f(float x, float y, float z)
{
	if (type_ != Parameter::Float3)
	{
		return false;
	}

	static_cast<float*>(value_)[0] = x;
	static_cast<float*>(value_)[1] = y;
	static_cast<float*>(value_)[2] = z;

	return true;
}
bool Parameter::setValue3vf(const float value[])
{
	if (type_ != Parameter::Float3)
	{
		return false;
	}

	static_cast<float*>(value_)[0] = value[0];
	static_cast<float*>(value_)[1] = value[1];
	static_cast<float*>(value_)[2] = value[2];

	return true;
}

bool Parameter::getValue4f(float& x, float& y, float& z, float& w) const
{
	if (type_ != Parameter::Float4)
	{
		return false;
	}

	x = static_cast<const float*>(value_)[0];
	y = static_cast<const float*>(value_)[1];
	z = static_cast<const float*>(value_)[2];
	w = static_cast<const float*>(value_)[3];

	return true;
}

bool Parameter::setValue4f(float x, float y, float z, float w)
{
	if (type_ != Parameter::Float4)
	{
		return false;
	}

	static_cast<float*>(value_)[0] = x;
	static_cast<float*>(value_)[1] = y;
	static_cast<float*>(value_)[2] = z;
	static_cast<float*>(value_)[3] = w;

	return true;
}

bool Parameter::setValue4vf(const float value[])
{
	if (type_ != Parameter::Float4)
	{
		return false;
	}

	static_cast<float*>(value_)[0] = value[0];
	static_cast<float*>(value_)[1] = value[1];
	static_cast<float*>(value_)[2] = value[2];
	static_cast<float*>(value_)[3] = value[3];

	return true;
}

bool Parameter::setValueTexture2D(const std::string& file_name)
{
	if (file_name.empty())
	{
		HY_ASSERT(0);
		return false;
	}

	Image* image = new Image;

	image->load(file_name);


	Texture2D* tex = rc_getTexMgr()->createRes2d();

	HY_ASSERT(tex->load(image));

	return true;
}

Texture2D* Parameter::getValueTexture2D() const
{
	return static_cast<Texture2D*>(value_);
}

Parameter::Parameter(ParameterManager* mgr, uint32 type, const std::string& name)
: mgr_(mgr)
, type_(type)
, name_(name)
{

}

Parameter::~Parameter()
{

}

}